#pragma once

#include "opencv2/opencv.hpp"
#include <string>
#include <Windows.h>
#include "slStruct.h"

#ifndef slLog
#define slLog Log::getInstance()
#endif

using namespace cv;

namespace SL
{
    ImageWithParam *readImageWithParam(std::string filename)
    {
        // Mat _image = imread(filename);
        // Mat image;
        // resize(_image, image, Size(_image.size().width / 2, _image.size().height / 2));
        // for (int h = 0; h < image.size().height; h++)
        // {
        //     for (int w = 0; w < image.size().width; w++)
        //     {
        //         uint8_t color = image.at<Vec3b>(h, w)[0];
        //         image.at<Vec3b>(h, w)[0] = color;
        //         image.at<Vec3b>(h, w)[1] = color;
        //         image.at<Vec3b>(h, w)[2] = color;
        //     }
        // }
        // imwrite("D:\\code\\amiraSl\\test\\gray.png", image);

        Mat image = imread(filename, -1);
        // std::cout << image.channels() << std ::endl;
        // cvtColor(image, image, CV_BGR2GRAY);
        // imshow("hi", image);
        // waitKey(0);
        // cvtColor(image, image, COLOR_BayerGBRG2BGR);
        // std::string wfilename = "D:\\code\\amiraSl\\test\\gray.png";
        // imwrite(wfilename, image);

        // for (int h = 0; h < image.size().height; h++)
        // {
        //     for (int w = 0; w < image.size().width; w++)
        //     {
        //         uint8_t color = image.at<Vec3b>(h, w)[0];
        //         image.at<Vec3b>(h, w)[0] = color;
        //         image.at<Vec3b>(h, w)[1] = color;
        //         image.at<Vec3b>(h, w)[2] = color;
        //     }
        // }
        // imwrite("D:\\code\\amiraSl\\test\\gray.png", image);
        int width = image.cols;
        int height = image.rows;
        ImageWithParam *imageWithParam = new ImageWithParam({image, height, width, filename});
        return imageWithParam;
    }

    std::vector<std::string> getAllFilenamesWithinFolder(std::string folder)
    {
        std::vector<std::string> names;
        std::string search_path = folder + "/*.*";
        WIN32_FIND_DATA fd;
        HANDLE hFind = FindFirstFile(search_path.c_str(), &fd);
        if (hFind != INVALID_HANDLE_VALUE)
        {
            do
            {
                if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
                {
                    names.push_back(fd.cFileName);
                }
            } while (FindNextFile(hFind, &fd));
            FindClose(hFind);
        }
        return names;
    }

    std::vector<std::string> getAllFoldersWithinFolder(std::string folder)
    {
        std::vector<std::string> names;
        std::string search_path = folder + "/*.*";
        WIN32_FIND_DATA fd;
        HANDLE hFind = FindFirstFile(search_path.c_str(), &fd);
        if (hFind != INVALID_HANDLE_VALUE)
        {
            do
            {
                if (fd.cFileName[0] == 46)
                    continue;
                if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
                    names.push_back(folder + "\\" + fd.cFileName);
                }
            } while (FindNextFile(hFind, &fd) != 0);
            FindClose(hFind);
        }
        return names;
    }

    std::vector<SL::ImageWithParam *> readCameraImages(std::string filePath, size_t no = 0)
    {
        std::vector<SL::ImageWithParam *> container;
        auto filenames = SL::getAllFilenamesWithinFolder(filePath);
        std::vector<SL::ImageWithParam> *result{};
        no = no == 0 ? filenames.size() : no;
        for (size_t i = 0; i < no; i++)
        {
            auto filename = filenames[i];
            auto extension = filename.substr(filename.find_last_of(".") + 1);
            if (extension != "png" && extension != "jpg" && extension != "jpeg" && extension != "bmp")
                continue;
            SL::ImageWithParam *imageWithParam = readImageWithParam(filePath + "\\" + filename);
            container.push_back(imageWithParam);
        }
        return container;
    }

    // void read(std::string filePath, int no = 0, std::string cameraFolder = "camera", std::string patternFolder = "pattern")
    // {
    //     SlContent &content = SL::SLContent::getInstance().getContent();
    //     readCameraImages(filePath + "\\" + cameraFolder, content.cameraImagesWithParam, no);
    //     readCameraImages(filePath + "\\" + patternFolder, content.patternImagesWithParam, no);
    //     content.cameraImageNo = (int)content.cameraImagesWithParam.size();
    //     content.patternImageNo = (int)content.patternImagesWithParam.size();
    //     content.imageHeight = content.cameraImagesWithParam[0]->height;
    //     content.imageWidth = content.cameraImagesWithParam[0]->width;
    //     content.imageSize = Size({content.imageWidth, content.imageHeight});
    //     slLog.log("Read %d images(s).", content.cameraImagesWithParam.size());
    //     // std::cout << "Read " << content.cameraImagesWithParam.size() << " image(s)" << std::endl;
    // }
}